package ca.swank.hq;

import ca.swank.hardquor.*;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class hqSimpleGUI extends JFrame implements hardquorUserGame
{
  private hqSimpleGUIpanel gamePanel;

  public hqSimpleGUI(hardquorGameClient gameClient, int playerNumber)
  {

    setTitle("HARDQUOR");
    setSize(415,520);
    setLocation(50,50);

    gamePanel = new hqSimpleGUIpanel(gameClient);

    getContentPane().add(gamePanel);

    addWindowListener(new hqSimpleGUICloseHandler(gameClient));

    setVisible(true);
  }

  public void notifyError(int errorCode)
  { System.out.println("error # " + errorCode);
  }

  public void notifyMove(int[] source, int[] target)
  { gamePanel.notifyMove(source, target);
  }

  public void notifyMove(int[] a1, int[] a2, int[] b1, int[] b2)
  { gamePanel.notifyMove(a1, a2, b1, b2);
  }

  public void notifySpeak(String user, String comment)
  { System.out.println(user + ":" + comment);
  }

  public void notifyTurn()
  { System.out.println("turn");
  }

  public void notifyWinner(String winnerName)
  { System.out.println("winner " + winnerName);
  }

  public void notifyQuit(String user)
  { setVisible(false);
  }


}


class hqSimpleGUIpanel extends JPanel implements ActionListener
{
  private hardquorBoard board;
  private MouseHandler responder;
  private hardquorGameClient gameClient;

  public static final int SQUARE_WIDTH = 30;
  public static final int SQUARE_HEIGHT = 30;
  public static final int SQUARE_WIDTH_TOTAL=40;
  public static final int SQUARE_HEIGHT_TOTAL=40;
  public static final int WALL_WIDTH=5;
  public static final int WALL_HEIGHT=5;
  public static final int START_X = 50;
  public static final int START_Y = 50;

  JTextField commentEnter;
  //JTextArea commentHistory;

  public static final Color COLOUR_WHITE = new Color(255,0,0);
  public static final Color COLOUR_BLACK = new Color(0,0,255);
  public static final Color COLOUR_NO_PLAYER = new Color(255,255,255);
  public static final Color COLOUR_NO_WALL = new Color(204,255,204);
  public static final Color COLOUR_OUT_OF_BOUNDS = new Color(0,153,0);
  public static final Color COLOUR_WALL = new Color(0,51,0);

  public static final Color COLOUR_BUTTON_ENABLED = new Color(225,225,225);
  public static final Color COLOUR_BUTTON_DISABLED = new Color(175,175,175);
  public static final Color COLOUR_BUTTON_TEXT = new Color(0,0,0);

  public hqSimpleGUIpanel(hardquorGameClient gameClient)
  {
	this.gameClient = gameClient;
    board = new hardquorSimpleBoard();
    responder = new MouseHandler(this, gameClient, board);

    commentEnter = new JTextField(20);
    //commentHistory = new JTextArea(5, 20);

    commentEnter.addActionListener(this);

    add(commentEnter);
    //add(commentHistory);

    addMouseListener(responder);
  }

  public void actionPerformed(ActionEvent e)
  { gameClient.speak(commentEnter.getText());
    commentEnter.setText("");
  }

  public void notifyMove(int[] source, int[] target)
  { board.makeMove(source, target);
    showBoard(board);
  }

  public void notifyMove(int[] a1, int[] a2, int[] b1, int[] b2)
  { board.makeMove(a1, a2, b1, b2);
    showBoard(board);
  }

  public void showBoard(hardquorBoard board)
  { this.board = board;
    responder.updateBoard(board);
    repaint();
  }

  public void paintComponent(Graphics g)
  {
	super.paintComponent(g);

	if(board.getWinner() == hardquorBoard.PLAYER_ONE) g.drawString("winner RED", 10,10);
	else if(board.getWinner() == hardquorBoard.PLAYER_TWO) g.drawString("winner BLUE", 10,10);
	else if(board.getTurn() == hardquorBoard.PLAYER_ONE) g.drawString("turn RED", 10,10);
	else if(board.getTurn() == hardquorBoard.PLAYER_TWO) g.drawString("turn BLUE", 10,10);

	g.drawString("RED walls: " + board.getPlayerWalls(hardquorBoard.PLAYER_ONE), 10,25);
	g.drawString("BLUE walls: " + board.getPlayerWalls(hardquorBoard.PLAYER_TWO), 10,40);


    for(int y = 0; y < board.getHeight(); y++)
    { for(int x = 0; x < board.getWidth(); x++)
      {
		int gy = board.getHeight() - y - 1;
		int gx = x;

		int[] coord = new int[] { x , y };

		if(board.getSquareOccupant(coord) == hardquorBoard.PLAYER_NONE)
        { g.setColor(COLOUR_NO_PLAYER);
	    } else if(board.getSquareOccupant(coord) == hardquorBoard.PLAYER_ONE)
	    { g.setColor(COLOUR_WHITE);
	    } else if(board.getSquareOccupant(coord) == hardquorBoard.PLAYER_TWO)
	    { g.setColor(COLOUR_BLACK);
	    }
	    g.fillRect(START_X + x*SQUARE_WIDTH_TOTAL,START_Y + gy*SQUARE_HEIGHT_TOTAL,SQUARE_WIDTH,SQUARE_HEIGHT);

        if(board.isAdjacent(coord, hardquorBoard.DIR_ABOVE))
        { g.setColor(COLOUR_NO_WALL);
	    } else
	    { g.setColor(COLOUR_WALL);
	    }

	    g.fillRect(START_X + x*SQUARE_WIDTH_TOTAL,START_Y + gy*SQUARE_HEIGHT_TOTAL - WALL_HEIGHT,SQUARE_WIDTH,WALL_HEIGHT);

        if(board.isAdjacent(coord, hardquorBoard.DIR_RIGHT))
        { g.setColor(COLOUR_NO_WALL);
	    } else
	    { g.setColor(COLOUR_WALL);
	    }

	    g.fillRect(START_X + x*SQUARE_WIDTH_TOTAL + SQUARE_WIDTH,START_Y + gy*SQUARE_HEIGHT_TOTAL,WALL_WIDTH,SQUARE_HEIGHT);

        if(board.isAdjacent(coord, hardquorBoard.DIR_BELOW))
        { g.setColor(COLOUR_NO_WALL);
	    } else
	    { g.setColor(COLOUR_WALL);
	    }

	    g.fillRect(START_X + x*SQUARE_WIDTH_TOTAL,START_Y + gy*SQUARE_HEIGHT_TOTAL+SQUARE_HEIGHT,SQUARE_WIDTH,WALL_HEIGHT);

        if(board.isAdjacent(coord, hardquorBoard.DIR_LEFT))
        { g.setColor(COLOUR_NO_WALL);
	    } else
	    { g.setColor(COLOUR_WALL);
	    }
	    g.fillRect(START_X + x*SQUARE_WIDTH_TOTAL - WALL_WIDTH,START_Y + gy*SQUARE_HEIGHT_TOTAL,WALL_WIDTH,SQUARE_HEIGHT);


      }
    }

  }

}

class MouseHandler extends MouseAdapter
{
  // for scaling clicks to appropriate size
  private hqSimpleGUIpanel p;

  // for sending moves to the board
  private hardquorGameClient gameClient;

  // for intelligently creating moves (knowing players turn etc)
  private hardquorBoard board;

  // because a wall takes two clicks, one click needs to be "saved" before a move is made
  private static final int HALF_NONE = 0;
  private static final int HALF_VERTICAL = 2;
  private static final int HALF_HORIZONTAL = 1;
  private int halfWall;
  private int halfX;
  private int halfY;

  public MouseHandler(hqSimpleGUIpanel panel, hardquorGameClient gameClient, hardquorBoard board)
  { p = panel;
    this.gameClient = gameClient;
    this.board = board;
    halfWall = HALF_NONE;
  }

  public void mouseReleased(MouseEvent e)
  { int gx = e.getX();
    int gy = e.getY();

    // undo
    if(gx >= 50 && gx <= 150 && gy >= 500 && gy <= 550)
    { System.out.print("undo!\n\n");
	  //game.undo();

    // redo
    } else if(gx >= 250 && gx <= 350 && gy >= 500 && gy <= 550)
    { System.out.print("redo!\n\n");
	  //game.redo(); */

    // click on board?
    } else
    {

      int x = (gx - p.START_X) / p.SQUARE_WIDTH_TOTAL;
      int y = hqBoard.BOARD_HEIGHT - 1 - ((gy - p.START_Y) / p.SQUARE_HEIGHT_TOTAL);

      // vertical wall move
      if(((gx - p.START_X) % p.SQUARE_WIDTH_TOTAL) > p.SQUARE_WIDTH)
      {
   	    if(halfWall != HALF_VERTICAL)
   	    { halfX = x;
	      halfY = y;
	      halfWall = HALF_VERTICAL;
	    } else
	    { /*hqMove move = new hqMove(board.getSquare(x,y), board.getSquare(halfX,halfY),
	                        board.getSquare(x+1,y), board.getSquare(halfX+1, halfY));*/
          halfWall = HALF_NONE;
          gameClient.tryMove(new int[] {x, y}, new int[] {halfX, halfY}, new int[] {x+1, y}, new int[] {halfX+1, halfY});
        }
      // horizontal wall move
      } else if(((gy - p.START_Y) % p.SQUARE_HEIGHT_TOTAL) > p.SQUARE_HEIGHT)
      {
 	    if(halfWall != HALF_HORIZONTAL)
	    { halfX = x;
	      halfY = y;
	      halfWall = HALF_HORIZONTAL;
	    } else
	    { /*hqMove move = new hqMove(board.getSquare(x,y), board.getSquare(halfX,halfY),
	                        board.getSquare(x,y-1), board.getSquare(halfX, halfY-1));*/
          halfWall = HALF_NONE;
          gameClient.tryMove(new int[] {x, y}, new int[] {halfX, halfY}, new int[] {x, y-1}, new int[] {halfX, halfY-1});
          //game.tryMove(move);
        }
      // walk move
      } else
      { //hqMove move = new hqMove(, board.getSquare(x,y));
        halfWall = HALF_NONE;
        /*game.tryMove(move);*/
        int[] playerLoc = board.getPlayerLocation(board.getTurn());
        gameClient.tryMove(playerLoc, new int[] {x, y});
      }

    }
  }

  public void updateBoard(hardquorBoard board)
  { this.board = board;
  }

}

class hqSimpleGUICloseHandler extends WindowAdapter
{
  public hardquorGameClient gameClient;

  public hqSimpleGUICloseHandler(hardquorGameClient gameClient)
  { this.gameClient = gameClient;
  }

  public void windowClosing(WindowEvent e)
  { gameClient.gameQuit();
  }

}